/**
  * @file		imu660ra.c
  * @brief		imu660ra姿态传感器头文件。
  * @note		1.使用前配置通信方式：
  *					SPI通信：#define COMMUNICATION_METHOD	(0)
  *					I2C通信：#define COMMUNICATION_METHOD	(1)
  *				2.使用CubeMX生成代码，勾选生成.c和.h文件。
  *				3.配置SPI的通信方式，CubeMX详细配置方式见47行：
  *					硬件SPI通信：#define SOFTWARE_SPI_ENABLE	(0)
  *					软件SPI通信：#define SOFTWARE_SPI_ENABLE	(1)
  * @author 	FFerryman
  * @date		2025-7-20
  * @version 	1.0
  */
#ifndef __IMU660RA_H
#define __IMU660RA_H

#ifdef __cplusplus
extern "C" {
#endif
/***********************头文件***********************/
#include "main.h"

/**********************参数配置**********************/
/**
  * @note   1.选择通信方式，对COMMUNICATION_METHOD进行配置，
  *         2.选择硬件/软件通信，对SOFTWARE_ENABLE进行配置。
  *         3.是否使能串口调试配置。
  *         4.对通信参数进行配置。
  */
/**
  * @brief	配置通信方式：
  *				0：SPI通信
  *				1：I2C通信
  */
#ifndef COMMUNICATION_METHOD
#define COMMUNICATION_METHOD	(1)
#endif
/**
  * @brief	软件通信使能配置：
  *				0：使用硬件通信
  *				1：使用软件通信
  */
#ifndef SOFTWARE_ENABLE
#define SOFTWARE_ENABLE		(0)
#endif
/**
  * @brief 	是否启用串口调试。
  *				0：禁止串口调试。
  *				1：使用串口调试。
  */
#ifndef	IMU660RA_DEBUG_ENABLE
#define	IMU660RA_DEBUG_ENABLE	(1)
#endif

#if COMMUNICATION_METHOD == 0 && SOFTWARE_ENABLE == 0
/**
  * @brief	硬件SPI通信相关配置。
  * @note	CubeMX中配置需注意：
  * 			使用全双工，禁用NSS、片选信号使用普通GPIO控制（初始输出电平为高电平）
  *    			Basic Parameters：
  *					Data Size = 8Bits（数据位长度）
  *					First Bit = MSB First(高位先行（LSB First低位先行）)
  *				Clock Parameters
  *					Prescaler (for Baud Rate)（分频得到通信速率）
  *					Baud Rate ≤ 20MBits/s（波特率≤20MHz）
  *					模式使用SPI模式0：
  *						Clock Polarity (CPOL) = Low(极性为低电平)
  *						Clock Phase (CPHA) = 1 Edge(第1边缘采集数据)
  *			
  */
#include "spi.h"
/**
  * @brief	硬件SPI通信句柄，需根据配置进行更改。
  */
#define IMU660RA_SPI_HANDLER	(hspi1)
/**
  * @brief	硬件SPI通信片选引脚PORT，需根据配置进行更改。
  */
#define IMU660RA_SPI_CS_PORT	(GPIOA)
/**
  * @brief	硬件SPI通信片选引脚PIN，需根据配置进行更改。
  */
#define IMU660RA_SPI_CS_PIN		(GPIO_PIN_4)
/**
  * @brief	硬件SPI通信使能。
  */
#define IMU660RA_SPI_ENABLE()	HAL_GPIO_WritePin(IMU660RA_SPI_CS_PORT, IMU660RA_SPI_CS_PIN, GPIO_PIN_RESET)
/**
  * @brief	硬件SPI通信失能。
  */
#define IMU660RA_SPI_DISABLE()	HAL_GPIO_WritePin(IMU660RA_SPI_CS_PORT, IMU660RA_SPI_CS_PIN, GPIO_PIN_SET)

#elif   COMMUNICATION_METHOD == 0 && SOFTWARE_ENABLE == 1
// 软件SPI通信


#elif   COMMUNICATION_METHOD == 1 && SOFTWARE_ENABLE == 0
/**
  * @brief	硬件I2C通信相关配置。
  * @note	CubeMX中配置需注意：
  *				Master Features：
  *					I2C Speed Mode：		Standard Mode（标准模式）或	Fast Mode（快速模式）
  *					I2C Clock Speed(Hz)：	100,000					或	400,000	
  *				Slave Features:
  *					Clock No Stretch Mode->Disable
  *					Primary Address Length selection->7-bit
  *					Dual Address Acknowledged->Disable
  *					Primary slave address->0
  *					General Call address detection->Disable
  */
#include "i2c.h"
/**
  * @brief	硬件I2C通信句柄，需根据配置进行更改。
  */
#define IMU660RA_I2C_HANDLER	(hi2c1)

#else
// 软件I2C通信
#endif

/********************基础参数定义********************/
typedef enum
{
    IMU660RA_ACC_SAMPLE_SGN_2G ,// 加速度计量程 ±2G  (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
    IMU660RA_ACC_SAMPLE_SGN_4G ,// 加速度计量程 ±4G  (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
    IMU660RA_ACC_SAMPLE_SGN_8G ,// 加速度计量程 ±8G  (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
    IMU660RA_ACC_SAMPLE_SGN_16G,// 加速度计量程 ±16G (ACC = Accelerometer 加速度计) (SGN = signum 带符号数 表示正负范围) (G = g 重力加速度 g≈9.80 m/s^2)
}imu660ra_acc_sample_config;

typedef enum
{
    IMU660RA_GYRO_SAMPLE_SGN_125DPS ,// 陀螺仪量程 ±125DPS  (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
    IMU660RA_GYRO_SAMPLE_SGN_250DPS ,// 陀螺仪量程 ±250DPS  (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
    IMU660RA_GYRO_SAMPLE_SGN_500DPS ,// 陀螺仪量程 ±500DPS  (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
    IMU660RA_GYRO_SAMPLE_SGN_1000DPS,// 陀螺仪量程 ±1000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
    IMU660RA_GYRO_SAMPLE_SGN_2000DPS,// 陀螺仪量程 ±2000DPS (GYRO = Gyroscope 陀螺仪) (SGN = signum 带符号数 表示正负范围) (DPS = Degree Per Second 角速度单位 °/S)
}imu660ra_gyro_sample_config;

#define IMU660RA_ACC_SAMPLE_DEFAULT   (IMU660RA_ACC_SAMPLE_SGN_8G)      // 在这设置默认的 加速度计 初始化量程
#define IMU660RA_GYRO_SAMPLE_DEFAULT  (IMU660RA_GYRO_SAMPLE_SGN_2000DPS)// 在这设置默认的 陀螺仪   初始化量程
#define IMU660RA_TIMEOUT_COUNT        (0x00FF)                          // IMU660 超时计数

/**********************参数定义**********************/
// SD0接地：0x68 SD0上拉：0x69 模块默认上拉
// 左移一位：SD0接地：0xD0 SD0上拉：0xD2	
#define IMU660RA_DEV_ADDR             (0x69)
#define IMU660RA_SPI_W                (0x00)
#define IMU660RA_SPI_R                (0x80)

#define IMU660RA_CHIP_ID              (0x00)
#define IMU660RA_PWR_CONF             (0x7C)
#define IMU660RA_PWR_CTRL             (0x7D)
#define IMU660RA_INIT_CTRL            (0x59)
#define IMU660RA_INIT_DATA            (0x5E)
#define IMU660RA_INT_STA              (0x21)
#define IMU660RA_ACC_ADDRESS          (0x0C)
#define IMU660RA_GYRO_ADDRESS         (0x12)
#define IMU660RA_ACC_CONF             (0x40)
#define IMU660RA_ACC_RANGE            (0x41)
#define IMU660RA_GYR_CONF             (0x42)
#define IMU660RA_GYR_RANGE            (0x43)

/**
  * @brief	加速度计量程配置。
  * @note	以下为25℃的转换比例,IMU660RA的加速度温漂系数为 0.004%/K,常值零偏的温度敏感系数为 ±0.25mg/K
  *			0x00:	量程为:±2g			获取的数据除以16384		得到物理数据		单位：g(m/s^2)
  *			0x01:	量程为:±4g			获取的数据除以8192		得到物理数据		单位：g(m/s^2)
  *			0x02:	量程为:±8g			获取的数据除以4096		得到物理数据		单位：g(m/s^2)
  *			0x03:	量程为:±16g		获取的数据除以2048		得到物理数据		单位：g(m/s^2)
  */
#define IMU660RA_ACC_SAMPLE         (0x02)
/**
  * @brief	陀螺仪量程配置。
  * @note	以下为25℃的转换比例,IMU660RA的陀螺仪温漂系数为0.02%/K,常值零偏的温度敏感系数为±0.015dps/K
  *			0x00:	量程为:±2000 dps	获取的数据除以16.384	得到物理数据		单位：°/s
  *			0x01:	量程为:±1000 dps	获取的数据除以32.768	得到物理数据		单位：°/s
  *			0x02:	量程为:±500  dps	获取的数据除以65.536	得到物理数据		单位：°/s
  *			0x03:	量程为:±250  dps	获取的数据除以131.072	得到物理数据		单位：°/s
  *			0x04:	量程为:±250  dps	获取的数据除以262.144	得到物理数据		单位：°/s
  */
#define IMU660RA_GYR_SAMPLE         (0x00)

/********************全局变量声明********************/ 
// 三轴陀螺仪数据GYRO(陀螺仪)
extern int16_t imu660ra_gyro_x, imu660ra_gyro_y, imu660ra_gyro_z;
// 三轴加速度计数据ACC(accelerometer 加速度计)
extern int16_t imu660ra_acc_x, imu660ra_acc_y, imu660ra_acc_z;
// 转换实际值的比例
extern float imu660ra_transition_factor[2];
//imu660ra配置数组
extern uint8_t imu660ra_config_file[8192];

/**********************函数声明**********************/
/**
  * @brief		将imu660ra加速度计数据转换为实际物理数据
  * @param		acc_value	任意轴的加速度计数据
  * @return		void
  * @example	float data = imu660ra_acc_transition(imu660ra_acc_x);/ 单位为 g(m/s^2)
  */
#define imu660ra_acc_transition(acc_value)      ((float)(acc_value) / imu660ra_transition_factor[0])

/**
  * @brief		将imu660ra陀螺仪数据转换为实际物理数据
  * @param		gyro_value	任意轴的陀螺仪数据
  * @return		void
  * @example	float data = imu660ra_gyro_transition(imu660ra_gyro_x);// 单位为 °/s
  */
#define imu660ra_gyro_transition(gyro_value)    ((float)(gyro_value) / imu660ra_transition_factor[1])

// 获取 imu660ra 加速度计数据
void    imu660ra_get_acc(void);
// 获取 imu660ra 陀螺仪数据
void    imu660ra_get_gyro(void);
// 初始化 imu660ra
uint8_t   imu660ra_init(void);
//imu660ra测试
void imu660ra_test(void);
#ifdef __cplusplus
}
#endif

#endif
